﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace genericity.实战
{
    public class Respository<T> where T:new()
    {
        // 可以把类型当做一种参数，这就是泛型的作用
        public void Add(T t)
        {
            // insert into Student(属性1，属性2，属性3...)values(属性值1，属性值2，属性值3...)
            StringBuilder sql = new StringBuilder($"insert into {typeof(T).Name}(");
            // 跳过第一个属性
            var propertyInfos = typeof(T).GetProperties().Skip(1);
            // 获取所有属性的名字
            var propNames = propertyInfos.Select(p => p.Name).ToList();
            sql.Append(string.Join(",", propNames));
            sql.Append(")values('");

            List<string>values = new List<string>();
            foreach (var propertyInfo in propertyInfos)
            {
                // 获取属性值
                values.Add(propertyInfo.GetValue(t).ToString());
            }
            sql.Append(string.Join("','", values));
            sql.Append("')");
            MySQLDBHelper.ExecuteNonQuery(sql.ToString());
        }

        public void Update(T t) 
        {
            // update table set name = 132,money = 123 where id = id
            StringBuilder sql = new StringBuilder($"update {typeof(T).Name} set ");
            // 跳过第一个属性
            var propertyInfos = typeof(T).GetProperties().Skip(1);
            var idvalue = typeof(T).GetProperty("id").GetValue(t);
            // 获取所有属性的名字

            var propList = propertyInfos.Select(p=> new { name=p.Name,money=p.GetValue(t) }).ToList();
            foreach (var item in propList)
            {
                sql.Append($"{item.name}='{item.money}',");
            }
            sql.Remove(sql.Length - 1, 1);
            sql.Append($" where id = {idvalue}");
            MySQLDBHelper.ExecuteNonQuery(sql.ToString());
        }

        public List<T> Select(Expression<Func<T,bool>>expression=null)
        {
            var table = typeof(T).Name;
            var sql = $"select * from {table}";
            return MySQLDBHelper.ExecuteQuery<T>(sql);
        }

        // 为什么要用dynamic：主键的类型有可能是Int,也有可能是string,uniqueidentifier,GUID,Long
        public T Get(dynamic id)
        {
            StringBuilder sql = new StringBuilder($"select * from {typeof(T).Name} where id = {id}");
            return MySQLDBHelper.ExecuteQueryOne<T>(sql.ToString());
        }

        public void Delete(dynamic id)
        {
            StringBuilder sql = new StringBuilder($"delete from {typeof(T).Name} where id = {id}");
            MySQLDBHelper.ExecuteNonQuery(sql.ToString());
        }

        public static List<T> GetList<T>(DataTable dataTable) where T : class, new()
        {
            List<T> list = new List<T>();

            var type = typeof(T);
            // 获取所有属性
            var propertyInfos = type.GetProperties();
            // 循环表中每一行数据
            foreach(DataRow dataTableRow in dataTable.Rows)
            {
                // 一定是要有new()这样的一个泛型约束
                T t = new T();
                foreach(var propertyInfo in propertyInfos)
                {
                    // 给每个属性都赋值
                    propertyInfo.SetValue(t,dataTableRow[propertyInfo.Name]);
                }
                list.Add(t);
            }
            return list;
        } 
    }
}
